{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import pickle\n",
    "import tensorflow as tf\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "from sklearn.metrics import roc_curve, auc\n",
    "from timeit import default_timer as timer\n",
    "import pickle\n",
    "from sklearn.preprocessing import LabelBinarizer\n",
    "\n",
    "# needed for plotting\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "import seaborn as sns\n",
    "current_palette = sns.color_palette()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'0.12.0-rc1'"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Using TensorFlow V.12\n",
    "tf.__version__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def getkey(item):\n",
    "    fpr, tpr, _ = roc_curve(test_labels.ravel(), test_preds[item])\n",
    "    roc_auc = auc(fpr, tpr)\n",
    "    return roc_auc\n",
    "\n",
    "def plotROC(testlabels, test_preds):\n",
    "    classifiers = list(test_preds.keys())\n",
    "\n",
    "    # Plot all ROC curves\n",
    "    plt.figure(figsize=(15,9))\n",
    "    for i, clf in zip(range(len(classifiers)), sorted(classifiers, key=getkey, reverse=True)):\n",
    "        fpr, tpr, _ = roc_curve(testlabels.ravel(), test_preds[clf] )\n",
    "        roc_auc = auc(fpr, tpr)\n",
    "        plt.plot(fpr, tpr,\n",
    "                 label='ROC curve '+ clf +  ' (area = {0:0.4f})'\n",
    "                       ''.format(roc_auc), linestyle='-', linewidth=2)\n",
    "\n",
    "\n",
    "    plt.plot([0, 1], [0, 1], 'k--', lw=2)\n",
    "    plt.xlim([-0.1, 1.0])\n",
    "    plt.ylim([0.0, 1.05])\n",
    "    plt.xlabel('False Positive Rate')\n",
    "    plt.ylabel('True Positive Rate')\n",
    "    plt.title('Comparison of multiclass ROC curves')\n",
    "    plt.legend(loc=\"lower right\", fontsize=14)\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Feature engineering. (not the best)\n",
    "Using same dataset as const_MFCC, difference is feature engineering  \n",
    "trying to manually take log of MFCC features."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "data = pickle.load(open('const_shape.p', 'rb'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "working dataframe's shape: (8730, 821)\n"
     ]
    }
   ],
   "source": [
    "data_cols = data.columns[:820]\n",
    "\n",
    "# removing last two samples, because 8730 is much easier to iterate evenly in different sized chunks than 8732.\n",
    "s = np.log(np.abs(data.loc[0:8729, data_cols]))\n",
    "s['label'] = data['label']\n",
    "print('working dataframe\\'s shape:', s.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "train shape (6984, 821)\n",
      "test  shape (1746, 821)\n",
      "iterable chunks: 1, 2, 3, 6, 9, 18, 97, 194, 291, 582, 873, 1746\n"
     ]
    }
   ],
   "source": [
    "# test train split.\n",
    "test_preds = {}\n",
    "train = s[0:6984]\n",
    "test = s[6984:]\n",
    "LB = LabelBinarizer().fit(train['label'])\n",
    "test_labels = LB.transform(test['label'])\n",
    "\n",
    "# print shapes\n",
    "print('train shape {}\\ntest  shape {}\\niterable chunks: 1, 2, 3, 6, 9, 18, 97, 194, 291, 582, 873, 1746'.format(train.shape, test.shape))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "del data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def accuracy(predictions, labels):\n",
    "    return (100.0 * np.sum(np.argmax(predictions, 1) == np.argmax(labels, 1))\n",
    "            / predictions.shape[0])\n",
    "\n",
    "def weight_variable(shape):\n",
    "    initial = tf.truncated_normal(shape, stddev=0.01)\n",
    "    return tf.Variable(initial)\n",
    "\n",
    "def bias_variable(shape):\n",
    "    initial = tf.constant(0.1, shape=shape)\n",
    "    return tf.Variable(initial)\n",
    "\n",
    "def test_accuracy(session, test_data=test, during = True):\n",
    "    test_data.reset_index(inplace=True, drop=True)\n",
    "    epoch_pred = session.run(prediction, feed_dict={tf_data : np.array(test_data.loc[0:check_size-1,data_cols]).reshape(check_size,20,41), keep_prob : 1.0})\n",
    "    for i in range(check_size, test_data.shape[0], check_size):\n",
    "        epoch_pred = np.concatenate([epoch_pred, session.run(prediction, \n",
    "                                    feed_dict={tf_data : np.array(test_data.loc[i:i+check_size-1,data_cols]).reshape(check_size,20,41), keep_prob : 1.0})], axis=0)\n",
    "    if during:\n",
    "        return accuracy(epoch_pred, test_labels)\n",
    "    else:\n",
    "        return epoch_pred"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "## Run Session"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "num_labels = 10\n",
    "batch_size = 97\n",
    "acc_over_time = {}\n",
    "def Run_Session(num_epochs, name, k_prob=1.0, mute=False, record=False):\n",
    "    global train\n",
    "    \n",
    "    start = timer()\n",
    "    with tf.Session(graph=graph) as session:\n",
    "        if record:\n",
    "            merged = tf.merge_all_summaries()  \n",
    "            writer = tf.train.SummaryWriter(\"/tmp/tensorflowlogs\", session.graph)\n",
    "        #tf.initialize_all_variables().run()\n",
    "        tf.global_variables_initializer().run()\n",
    "\n",
    "        print(\"Initialized\")\n",
    "        accu = []\n",
    "        \n",
    "        for epoch in range(num_epochs):\n",
    "            \n",
    "            # get batch\n",
    "            train_batch = train.sample(batch_size)\n",
    "            \n",
    "            t_d = np.asarray(train_batch[data_cols]).reshape(batch_size,20,41)\n",
    "            t_l = LB.transform(train_batch['label'])\n",
    "            \n",
    "            # make feed dict\n",
    "            feed_dict = { tf_data : t_d, train_labels : t_l, keep_prob : k_prob}\n",
    "            \n",
    "            # run model on batch\n",
    "            _, l, predictions = session.run([optimizer, loss, prediction], feed_dict=feed_dict)\n",
    "            \n",
    "            # mid model accuracy checks \n",
    "            if (epoch % 1000 == 0) and not mute:\n",
    "                print(\"\\tMinibatch loss at epoch {}: {}\".format(epoch, l))\n",
    "                print(\"\\tMinibatch accuracy: {:.1f}\".format(accuracy(predictions, t_l)))\n",
    "            if (epoch % 5000 == 0) and not mute:\n",
    "                print(\"Test accuracy: {:.1f}\".format(test_accuracy(session, during=True)))\n",
    "            if (epoch % 1000 == 0) and not mute:\n",
    "                accu.append(tuple([epoch, test_accuracy(session, during=True)]))\n",
    "                \n",
    "        # record accuracy and predictions\n",
    "        test_preds[name] = test_accuracy(session, during=False)\n",
    "        print(\"Final Test accuracy: {:.1f}\".format(accuracy(test_preds[name], test_labels)))\n",
    "        end = timer()\n",
    "        test_preds[name] = test_preds[name].ravel()\n",
    "        acc_over_time[name] = accu\n",
    "        print(\"time taken: {0} minutes {1:.1f} seconds\".format((end - start)//60, (end - start)%60))\n",
    "        #tf.train.export_meta_graph()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "## RNN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Basic RNN model made\n"
     ]
    }
   ],
   "source": [
    "# constants\n",
    "num_labels = 10\n",
    "batch_size = 97\n",
    "check_size = 97\n",
    "rows, cols = 20, 41\n",
    "n_hidden = 600\n",
    "beta = 0.04\n",
    "\n",
    "graph = tf.Graph()\n",
    "with graph.as_default():\n",
    "    # placeholders\n",
    "    tf_data = tf.placeholder(tf.float32, shape=[None, rows, cols])\n",
    "    train_labels = tf.placeholder(tf.float32, shape=[None, num_labels])\n",
    "    keep_prob = tf.placeholder(tf.float32)\n",
    "    \n",
    "    # weights and biases\n",
    "    layer1_weights = weight_variable([rows*n_hidden, num_labels])\n",
    "    layer1_biases = bias_variable([num_labels])\n",
    "    \n",
    "    # model\n",
    "    def model(data, proba=1.0):\n",
    "        \n",
    "        cell = tf.nn.rnn_cell.BasicLSTMCell(n_hidden, state_is_tuple=True)\n",
    "        #cell = tf.nn.rnn_cell.MultiRNNCell([ltsm] * 2, state_is_tuple=True)\n",
    "        layer1, _istate = tf.nn.dynamic_rnn(cell, data, dtype=tf.float32)\n",
    "        layer1 = tf.reshape(layer1, shape=[batch_size, rows*n_hidden])\n",
    "        layer2 = tf.nn.dropout(layer1, proba)\n",
    "        return tf.matmul(layer2, layer1_weights) + layer1_biases\n",
    "\n",
    "    # Training computation.\n",
    "    logits = model(tf_data, keep_prob)\n",
    "    loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits, train_labels) +\n",
    "                         beta*tf.nn.l2_loss(layer1_weights) +\n",
    "                         beta*tf.nn.l2_loss(layer1_biases))\n",
    "\n",
    "    # Optimizer.\n",
    "    optimizer = tf.train.AdamOptimizer(1e-4).minimize(loss)\n",
    "\n",
    "    # Predictions for the training, validation, and test data.\n",
    "    # !!!! as this model does not allow calling model more than once we will need to get test predictions\n",
    "    #      by running the test data through the same prediction op as the train data. !!!\n",
    "    # !!! make note to not run optimizer on same function call !!!\n",
    "    prediction = tf.nn.softmax(logits) \n",
    "    print('Basic RNN model made')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Initialized\n",
      "\tMinibatch loss at epoch 0: 2.567577600479126\n",
      "\tMinibatch accuracy: 15.5\n",
      "Test accuracy: 11.6\n",
      "\tMinibatch loss at epoch 1000: 1.383567452430725\n",
      "\tMinibatch accuracy: 60.8\n",
      "\tMinibatch loss at epoch 2000: 0.6954327821731567\n",
      "\tMinibatch accuracy: 83.5\n",
      "\tMinibatch loss at epoch 3000: 0.48941051959991455\n",
      "\tMinibatch accuracy: 85.6\n",
      "\tMinibatch loss at epoch 4000: 0.14809764921665192\n",
      "\tMinibatch accuracy: 100.0\n",
      "\tMinibatch loss at epoch 5000: 0.15992623567581177\n",
      "\tMinibatch accuracy: 96.9\n",
      "Test accuracy: 30.9\n",
      "\tMinibatch loss at epoch 6000: 0.11205485463142395\n",
      "\tMinibatch accuracy: 99.0\n",
      "\tMinibatch loss at epoch 7000: 0.15226969122886658\n",
      "\tMinibatch accuracy: 95.9\n",
      "\tMinibatch loss at epoch 8000: 0.09204017370939255\n",
      "\tMinibatch accuracy: 99.0\n",
      "\tMinibatch loss at epoch 9000: 0.10806972533464432\n",
      "\tMinibatch accuracy: 96.9\n",
      "\tMinibatch loss at epoch 10000: 0.07949729263782501\n",
      "\tMinibatch accuracy: 99.0\n",
      "Test accuracy: 32.5\n",
      "\tMinibatch loss at epoch 11000: 0.05226586014032364\n",
      "\tMinibatch accuracy: 99.0\n",
      "\tMinibatch loss at epoch 12000: 0.05476831644773483\n",
      "\tMinibatch accuracy: 99.0\n",
      "\tMinibatch loss at epoch 13000: 0.03840486332774162\n",
      "\tMinibatch accuracy: 100.0\n",
      "\tMinibatch loss at epoch 14000: 0.12734785676002502\n",
      "\tMinibatch accuracy: 94.8\n",
      "\tMinibatch loss at epoch 15000: 0.069489486515522\n",
      "\tMinibatch accuracy: 97.9\n",
      "Test accuracy: 32.9\n",
      "\tMinibatch loss at epoch 16000: 0.05016836151480675\n",
      "\tMinibatch accuracy: 100.0\n",
      "\tMinibatch loss at epoch 17000: 0.08603905886411667\n",
      "\tMinibatch accuracy: 96.9\n",
      "\tMinibatch loss at epoch 18000: 0.07795117050409317\n",
      "\tMinibatch accuracy: 96.9\n",
      "\tMinibatch loss at epoch 19000: 0.061859190464019775\n",
      "\tMinibatch accuracy: 97.9\n",
      "Final Test accuracy: 33.3\n",
      "time taken: 269.0 minutes 28.3 seconds\n"
     ]
    }
   ],
   "source": [
    "Run_Session(20000, 'RNN', .2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## DeepNN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Basic DeepNN model made\n"
     ]
    }
   ],
   "source": [
    "# constants\n",
    "num_labels = 10\n",
    "\n",
    "batch_size = 97\n",
    "check_size = 582\n",
    "rows, cols = 20, 41\n",
    "\n",
    "n_hidden1 = 1200\n",
    "n_hidden2 = 1500\n",
    "n_hidden3 = 1200\n",
    "\n",
    "beta = 0.01\n",
    "\n",
    "graph = tf.Graph()\n",
    "with graph.as_default():\n",
    "    # placeholders\n",
    "    tf_data = tf.placeholder(tf.float32, shape=[None, rows, cols])\n",
    "    train_labels = tf.placeholder(tf.float32, shape=[None, num_labels])\n",
    "    keep_prob = tf.placeholder(tf.float32)\n",
    "    \n",
    "    # weights and biases\n",
    "    layer1_weights = weight_variable([rows*cols, n_hidden1])\n",
    "    layer1_biases = bias_variable([n_hidden1])\n",
    "    layer2_weights = weight_variable([n_hidden1, n_hidden2])\n",
    "    layer2_biases = bias_variable([n_hidden2])\n",
    "    layer3_weights = weight_variable([n_hidden2, n_hidden3])\n",
    "    layer3_biases = bias_variable([n_hidden3])\n",
    "    layer4_weights = weight_variable([n_hidden3, num_labels])\n",
    "    layer4_biases = bias_variable([num_labels])\n",
    "\n",
    "    # model\n",
    "    def model(data, proba=1.0):\n",
    "        \n",
    "        layer1 = tf.nn.relu(tf.matmul(tf.reshape(data, [-1, rows*cols]), layer1_weights) + layer1_biases)\n",
    "        layer1 = tf.nn.dropout(layer1, proba)\n",
    "        \n",
    "        layer2 = tf.nn.relu(tf.matmul(layer1, layer2_weights) + layer2_biases)\n",
    "        layer2 = tf.nn.dropout(layer2, proba)\n",
    "        \n",
    "        layer3 = tf.nn.relu(tf.matmul(layer2, layer3_weights) + layer3_biases)\n",
    "        layer3 = tf.nn.dropout(layer3, proba)\n",
    "        \n",
    "        return tf.matmul(layer3, layer4_weights) + layer4_biases\n",
    "\n",
    "    # Training computation.\n",
    "    logits = model(tf_data, keep_prob)\n",
    "    loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits, train_labels) +\n",
    "                         beta*tf.nn.l2_loss(layer1_weights) +\n",
    "                         beta*tf.nn.l2_loss(layer1_biases) +\n",
    "                         beta*tf.nn.l2_loss(layer2_weights) +\n",
    "                         beta*tf.nn.l2_loss(layer2_biases) +\n",
    "                         beta*tf.nn.l2_loss(layer3_weights) +\n",
    "                         beta*tf.nn.l2_loss(layer3_biases) +\n",
    "                         beta*tf.nn.l2_loss(layer4_weights) +\n",
    "                         beta*tf.nn.l2_loss(layer4_biases))\n",
    "\n",
    "    # Optimizer.\n",
    "    optimizer = tf.train.AdamOptimizer(1e-4).minimize(loss)\n",
    "\n",
    "    # Predictions for the training, validation, and test data.\n",
    "    # !!!! as this RNN model does not allow calling model more than once we will need to get test predictions\n",
    "    #      by running the test data through the same prediction op as the train data. !!!\n",
    "    # !!! make note to not run optimizer on same function call !!!\n",
    "    prediction = tf.nn.softmax(logits)  \n",
    "    print('Basic DeepNN model made')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "Run_Session(10000, 'DeepNN', .5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## CNN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Basic CNN model made\n"
     ]
    }
   ],
   "source": [
    "# single layer CNN\n",
    "num_labels = 10\n",
    "\n",
    "batch_size = 97\n",
    "check_size = 582\n",
    "rows, cols = 20, 41\n",
    "patch_size = 5\n",
    "num_channels = 1\n",
    "depth1 = 32\n",
    "\n",
    "num_hidden = 2050\n",
    "\n",
    "beta = 0.01\n",
    "\n",
    "graph = tf.Graph()\n",
    "with graph.as_default():\n",
    "    \n",
    "    tf_data = tf.placeholder(tf.float32, shape=(None, rows, cols))\n",
    "    train_labels = tf.placeholder(tf.float32, shape=(None, num_labels))\n",
    "    #tf_test_dataset = tf.placeholder(tf.float32, shape=(check_size, image_size, image_size, num_channels))\n",
    "\n",
    "    # Variables.\n",
    "    layer1_weights = weight_variable([patch_size, patch_size, 1, depth1])\n",
    "    layer1_biases = bias_variable([depth1])\n",
    "    layer2_weights = weight_variable([rows//2 * (cols//2 + 1) * depth1, num_hidden])\n",
    "    layer2_biases = bias_variable([num_hidden])\n",
    "    layer3_weights = weight_variable([num_hidden, num_labels])\n",
    "    layer3_biases = bias_variable([num_labels])\n",
    "\n",
    "    keep_prob = tf.placeholder(tf.float32)\n",
    "    # Model with dropout\n",
    "    def model(data, proba=keep_prob):\n",
    "        # Convolution\n",
    "        conv1 = tf.nn.conv2d(data, layer1_weights, [1, 2, 2, 1] , padding='SAME') + layer1_biases\n",
    "        pooled1 = tf.nn.max_pool(tf.nn.relu(conv1), ksize=[1, 2, 2, 1],strides=[1, 1, 1, 1], padding='SAME')\n",
    "\n",
    "        # Fully Connected Layer\n",
    "        shape = pooled1.get_shape().as_list()\n",
    "        reshape = tf.reshape(pooled1, [-1, shape[1] * shape[2] * shape[3]])\n",
    "        full2 = tf.nn.relu(tf.matmul(reshape, layer2_weights) + layer2_biases)\n",
    "\n",
    "        # Dropout\n",
    "        full2 = tf.nn.dropout(full2, proba)\n",
    "        \n",
    "        return tf.matmul(full2, layer3_weights) + layer3_biases\n",
    "\n",
    "    # Training computation.\n",
    "    logits = model(tf.expand_dims(tf_data, -1), keep_prob)\n",
    "    loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits, train_labels) +\n",
    "                         beta*tf.nn.l2_loss(layer1_weights) +\n",
    "                         beta*tf.nn.l2_loss(layer1_biases) +\n",
    "                         beta*tf.nn.l2_loss(layer2_weights) +\n",
    "                         beta*tf.nn.l2_loss(layer2_biases) +\n",
    "                         beta*tf.nn.l2_loss(layer3_weights) +\n",
    "                         beta*tf.nn.l2_loss(layer3_biases))\n",
    "\n",
    "    # Optimizer.\n",
    "    optimizer = tf.train.AdamOptimizer(1e-4).minimize(loss)\n",
    "\n",
    "    # Predictions for the training, validation, and test data.\n",
    "    prediction = tf.nn.softmax(logits)\n",
    "    #test_prediction = tf.nn.softmax(model(tf_test_dataset,1.0))  \n",
    "    print('Basic CNN model made')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Initialized\n",
      "\tMinibatch loss at epoch 0: 7.75794792175293\n",
      "\tMinibatch accuracy: 6.2\n",
      "Test accuracy: 12.4\n",
      "\tMinibatch loss at epoch 1000: 1.982966423034668\n",
      "\tMinibatch accuracy: 35.1\n",
      "\tMinibatch loss at epoch 2000: 1.7484956979751587\n",
      "\tMinibatch accuracy: 44.3\n",
      "\tMinibatch loss at epoch 3000: 1.5821635723114014\n",
      "\tMinibatch accuracy: 54.6\n",
      "\tMinibatch loss at epoch 4000: 1.4924242496490479\n",
      "\tMinibatch accuracy: 57.7\n",
      "\tMinibatch loss at epoch 5000: 1.5107589960098267\n",
      "\tMinibatch accuracy: 58.8\n",
      "Test accuracy: 37.2\n",
      "\tMinibatch loss at epoch 6000: 1.1542561054229736\n",
      "\tMinibatch accuracy: 77.3\n",
      "\tMinibatch loss at epoch 7000: 1.1912972927093506\n",
      "\tMinibatch accuracy: 77.3\n",
      "\tMinibatch loss at epoch 8000: 1.0234284400939941\n",
      "\tMinibatch accuracy: 81.4\n",
      "\tMinibatch loss at epoch 9000: 1.0523602962493896\n",
      "\tMinibatch accuracy: 83.5\n",
      "\tMinibatch loss at epoch 10000: 0.9625751972198486\n",
      "\tMinibatch accuracy: 89.7\n",
      "Test accuracy: 40.0\n",
      "\tMinibatch loss at epoch 11000: 0.954519510269165\n",
      "\tMinibatch accuracy: 85.6\n",
      "\tMinibatch loss at epoch 12000: 0.9440872073173523\n",
      "\tMinibatch accuracy: 88.7\n",
      "\tMinibatch loss at epoch 13000: 0.9639616012573242\n",
      "\tMinibatch accuracy: 87.6\n",
      "\tMinibatch loss at epoch 14000: 0.9320002198219299\n",
      "\tMinibatch accuracy: 87.6\n",
      "\tMinibatch loss at epoch 15000: 0.8431679010391235\n",
      "\tMinibatch accuracy: 90.7\n",
      "Test accuracy: 37.9\n",
      "\tMinibatch loss at epoch 16000: 0.7953998446464539\n",
      "\tMinibatch accuracy: 93.8\n",
      "\tMinibatch loss at epoch 17000: 0.7752459645271301\n",
      "\tMinibatch accuracy: 93.8\n",
      "\tMinibatch loss at epoch 18000: 0.8292020559310913\n",
      "\tMinibatch accuracy: 92.8\n",
      "\tMinibatch loss at epoch 19000: 0.8405120968818665\n",
      "\tMinibatch accuracy: 89.7\n",
      "Final Test accuracy: 37.7\n",
      "time taken: 654.0 minutes 20.5 seconds\n"
     ]
    }
   ],
   "source": [
    "Run_Session(20000, 'CNN', .5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\noosuYt++fQC88cYbXHrppWe9USIiInKqSY+07777bu677z4sy2LJkiWsW7duOtolIiIiJzHskTep\nRUREpGqVZXMVERERmTqFtoiISI1QaIuIiNSISS9EmwzbtnnggQf4y1/+gtvt5pFHHmHhwoXTeUmZ\nhK9+9av4/X4AFixYwJYtW9i2bRumabJs2TJ27NgBwIsvvsgLL7yAy+Viy5YtXHXVVaRSKe688076\n+vrw+/089thjNDc3V/LbmTUOHDjAD3/4Q5599lmOHDky5T7bv38/jz76KE6nkyuuuIJbb721wt/h\nzDWy795//31uvvlmFi9eDMD111/P+vXr1XdVKJPJcO+999LV1YVlWWzZsoWlS5dW5mfPnka//vWv\n7W3bttm2bdv79++3b7nllum8nExCKpWyr7vuulGPbdmyxd63b59t27Z9//3327/5zW/sUChkb9y4\n0bYsy45Go/bGjRvtdDptP/PMM/YTTzxh27Zt/+pXv7J37txZ9u9hNvrZz35mb9y40f76179u2/bZ\n6bNrr73W/vjjj23btu1vfetb9vvvv1+B72zmO7nvXnzxRfuZZ54Z9TXqu+r00ksv2Y8++qht27Y9\nODhoX3XVVRX72ZvW6fF33nmHL37xiwCsWrWK9957bzovJ5Nw+PBhEokEHR0dbN68mQMHDnDo0KFR\nW9S+9dZbvPvuu1x66aU4nU78fj+LFy/m8OHDvPPOO6xZs6b4taVsZytTN9G2wpPpsz/84Q/EYjEs\ny2LBggUAfOELX+Ctt94q/zc2C4zVd6+99hqbNm1i+/btxONx9V2VWr9+PVu3bgUgm83icDim9O/l\nVPpvWkM7FosRCJzYzcfpdJLL5abzklKi+vp6Ojo6+PnPf84DDzzA9773vVO2qI3FYsTj8VF96PV6\ni48XptYLXyvTb6JthSfTZ9FodNRjIx+Xs+/kvlu1ahV33XUXu3fvZuHChfz0pz895d9M9V118Hg8\nxb7YunUrt99+e8V+9qY1tP1+P/F4vPh5LpcbtQ2qVM7ixYv58pe/XPy4qamJvr6+4vOFLWr9fv+o\nQB75eKFvT/4fVcpnrG2FJ9NnJ//CNZmtiWVq1q5dy0UXXVT8+PDhwwQCAfVdlTp27Bjf/OY3ue66\n69iwYUPFfvamNUEvueQSXn/9dQD279/PBRdcMJ2Xk0l46aWXeOyxxwDo7u4mFotx5ZVX8vbbbwMn\ntqhduXIl77zzDul0mmg0ygcffMCyZcv47Gc/W+zb119/vThNJOU11rbCk+kzv9+P2+3m448/jPEF\nRAAAATlJREFUxrZt3nzzTW1NXCYdHR38+c9/BmDv3r2sWLFCfVelent76ejo4M477+S6664DYPny\n5RX52ZvWHdHsEavHIX8W93nnnTddl5NJsCyLe+65h6NHj2KaJnfeeSdNTU3Fs9OXLFnCzp07MQyD\nX/ziF7zwwgvYts0tt9zC2rVrSSaT3H333YRCIdxuNz/60Y9obW2t9Lc1K3R1dfHd736X559/no8+\n+mjUtsJn0mfvvvsujzzyCLlcjiuvvJLbbrut0t/ijDWy7w4dOsTDDz+My+UiGAzy0EMP4fP51HdV\n6JFHHuHVV1/l/PPPx7ZtDMOgs7OTnTt3lv1nT9uYioiI1AjdYBYREakRCm0REZEaodAWERGpEQpt\nERGRGqHQFhERqREKbRERkRqh0BYREakRCm0REZEa8f8B8CKRL+4EzSIAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1e1805f5668>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(np.array(acc_over_time['RNN'])[:,0], np.array(acc_over_time['RNN'])[:,1])\n",
    "plt.plot(np.array(acc_over_time['DeepNN'])[:,0], np.array(acc_over_time['DeepNN'])[:,1])\n",
    "plt.plot(np.array(acc_over_time['CNN'])[:,0], np.array(acc_over_time['CNN'])[:,1])\n",
    "plt.title('Accuracy')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# record measurements\n",
    "#dataset_acc = pickle.load(open('dataset_acc.p','rb'))\n",
    "dataset_acc['const_LogMFCC'] = {'DeepNN':np.array(acc_over_time['DeepNN'])[-1,1],\n",
    "                              'RNN': np.array(acc_over_time['RNN'])[-1,1],\n",
    "                              'CNN': np.array(acc_over_time['CNN'])[-1,1]}\n",
    "#pickle.dump(dataset_acc, open('dataset_acc.p','wb'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'const_LogMFCC': {'CNN': 39.34707903780069,\n",
       "  'DeepNN': 34.306987399770904,\n",
       "  'RNN': 33.218785796105387},\n",
       " 'features193': {'CNN': 65.4639175257732,\n",
       "  'DeepNN': 63.57388316151203,\n",
       "  'RNN': 60.53837342497136}}"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataset_acc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "plotROC(test_labels, test_preds)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python [Root]",
   "language": "python",
   "name": "Python [Root]"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
